//-----------------------------------------------------------------------
// <copyright file="ContactCollection.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.Live.Messenger
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using Microsoft.Live.Core;

    /// <summary>
    /// Represents a collection of contacts.
    /// </summary>
    /// <remarks>
    /// Use the methods of ContactCollection to add contacts to the collection, remove contacts from the collection, and search for contacts within the collection.
    /// </remarks>
    public sealed class ContactCollection : Collection
    {
        internal ContactCollection(object obj, User user)
            : base(obj, user)
        {
        }

        /// <summary>
        /// Gets the maximum number of contacts that the User can have within this collection.
        /// </summary>
        public int Capacity
        {
            get { return this.Entity.GetNumberProperty<int>("Capacity"); }
        }

        /// <summary>
        /// Adds a contact to the collection.
        /// </summary>
        /// <param name="contact">The contact to add.</param>
        public void Add(Contact contact)
        {
            if (contact == null)
            {
                throw ExceptionHelper.CreateArgumentNullException("contact");
            }

            if (this.Contains(contact))
            {
                throw ExceptionHelper.CreateArgumentException("Contact already belongs to the collection", "contact");
            }

            this.Entity.Invoke("Add", contact.Entity);
        }

        /// <summary>
        /// Removes a contact from the collection.
        /// </summary>
        /// <param name="contact">The contact to remove.</param>
        public void Remove(Contact contact)
        {
            if (contact == null)
            {
                throw ExceptionHelper.CreateArgumentNullException("contact");
            }

            if (!this.Contains(contact))
            {
                throw ExceptionHelper.CreateArgumentException("Contact does not belong to the collection", "contact");
            }

            this.Entity.Invoke("Remove", contact.Entity);
        }

        /// <summary>
        ///     Attempts to find a <see cref="Contact"/>.
        /// </summary>
        /// <param name="address">The IM address of the contact</param>.
        /// <returns>A <see cref="Contact"/> object if found; <c>null</c> otherwise</returns>.
        public Contact FindByAddress(IMAddress address)
        {
            if (address == null)
            {
                throw ExceptionHelper.CreateArgumentNullException("address");
            }

            return this.User.ContactFactory.FindOrCreate(
                this.Entity.Invoke("FindByAddress", address.Entity));
        }

        /// <summary>
        ///     Attempts to find a <see cref="Contact"/>.
        /// </summary>
        /// <param name="address">The address of the contact</param>.
        /// <param name="addressType">The address type of the contact</param>.
        /// <returns>A <see cref="Contact"/> object if found; <c>null</c> otherwise</returns>.
        public Contact Find(string address, IMAddressType addressType)
        {
            if (String.IsNullOrEmpty(address))
            {
                throw ExceptionHelper.CreateArgumentNullException("address");
            }

            return this.User.ContactFactory.FindOrCreate(
                this.Entity.Invoke("Find", address, addressType));
        }

        internal override object FindOrCreate(MessengerEntity entity)
        {
            return this.User.ContactFactory.FindOrCreate(entity);
        }
    }
}